package com.ibm.cloud.envcheck.service;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.ibm.cloud.envcheck.bean.RemoteParam;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;

public abstract class RemoteBasicService <T extends RemoteParam>implements ICheckService<T>{

	protected ChannelExec channel;
	private Session session;
	protected OutputStream out;

	protected InputStream in;
	protected FileOutputStream fos = null;

	public abstract void handle(T t);

	public OutputStream getOut() {
		return out;
	}

	public InputStream getIn() {
		return in;
	}

	public FileOutputStream getFos() {
		return fos;
	}

	public void initChannel(RemoteParam param) {
		JSch jsch = new JSch();
		try {
			session = jsch.getSession(param.getUsername(), param.getHost(), param.getPort());
			UserInfo user = new RemoteUserInfor(param.getPassword());
			session.setUserInfo(user);
			session.setTimeout(5000);
			session.connect();

			channel = (ChannelExec) session.openChannel("exec");
			channel.setCommand(param.getCommand());
			out = channel.getOutputStream();
			in = channel.getInputStream();

			channel.connect();
			
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		} catch (IOException e) {
			// log here
			e.printStackTrace();
		} catch (JSchException e) {
			// log here
			e.printStackTrace();
		}
	}

	/**
	 * close session and channle
	 * 
	 */
	public void destroy() {
		if (!channel.isClosed() && channel.isConnected()) {
			channel.disconnect();
		}
		if (session.isConnected()) {
			session.disconnect();
		}
	}

	/**
	 * come from Jsch
	 * 
	 * @author macky
	 *
	 */
	private class RemoteUserInfor implements UserInfo {
		private String passwd;

		public RemoteUserInfor(String passwd) {
			this.passwd = passwd;
		}

		@Override
		public String getPassphrase() {

			return null;
		}

		@Override
		public String getPassword() {
			return passwd;
		}

		@Override
		public boolean promptPassphrase(String arg0) {

			return false;
		}

		@Override
		public boolean promptPassword(String arg0) {
			return true;
		}

		@Override
		public boolean promptYesNo(String arg0) {
			return true;
		}

		@Override
		public void showMessage(String arg0) {
		}

	}

	protected int checkAck(InputStream in) throws IOException {
		int b = in.read();
		// b may be
		// 0 for success,
		// 1 for error,
		// 2 for fatal error,
		// -1
		if (b == 0)
			return b;
		if (b == -1)
			return b;

		if (b == 1 || b == 2) {
			StringBuffer sb = new StringBuffer();
			int c;
			do {
				c = in.read();
				sb.append((char) c);
			} while (c != '\n');
			if (b == 1) { // error
				System.out.print(sb.toString());
			}
			if (b == 2) { // fatal error
				System.out.print(sb.toString());
			}
		}
		return b;
	}
	
	public void printResult(InputStream inputStream){
		byte[] tmp = new byte[1024];
		try {
			while (true) {
				while (inputStream.available() > 0) {
					int i = inputStream.read(tmp, 0, 1024);
					if (i < 0)
						break;
					System.out.print(new String(tmp, 0, i));
				}
				if (channel.isClosed()) {
					if (inputStream.available() > 0)
						continue;
					break;
				}
				try {
					Thread.sleep(2000);
				} catch (Exception ee) {
				}
			}
		} catch (Exception e) {
		}
	}

}
